#include"StdAfx.h"

pgPrimitiveCube::pgPrimitiveCube()
{
	m_pVertexBuffer = NULL;
	m_pIndexBuffer = NULL;
	m_pConstantBuffer = NULL;

	m_worldTransformMatrix = pgMat44::Identity();
}
pgPrimitiveCube::~pgPrimitiveCube()
{
	PG_SAFE_RELEASE(m_pVertexBuffer);
	PG_SAFE_RELEASE(m_pIndexBuffer);
	PG_SAFE_RELEASE(m_pConstantBuffer)
}



bool pgPrimitiveCube::Load()
{
	PG_SAFE_RELEASE(m_pVertexBuffer);
	PG_SAFE_RELEASE(m_pIndexBuffer);

	SVertex verts[] =
	{
		 XMFLOAT3( -1.0f, 1.0f, -1.0f ),
         XMFLOAT3( 1.0f, 1.0f, -1.0f ),
         XMFLOAT3( 1.0f, 1.0f, 1.0f ),
         XMFLOAT3( -1.0f, 1.0f, 1.0f ),
         XMFLOAT3( -1.0f, -1.0f, -1.0f ),
         XMFLOAT3( 1.0f, -1.0f, -1.0f ),
         XMFLOAT3( 1.0f, -1.0f, 1.0f ),
         XMFLOAT3( -1.0f, -1.0f, 1.0f ),
	};

	m_nVertexCount = ARRAYSIZE(verts);

	WORD indices[] = 
	{
		3,1,0,
        2,1,3,

        0,5,4,
        1,5,0,

        3,4,7,
        0,4,3,

        1,6,5,
        2,6,1,

        2,7,6,
        3,7,2,

        6,4,5,
        7,4,6,

	};
	m_nIndexCount = ARRAYSIZE(indices);
	D3D11_BUFFER_DESC bd;
	ZeroMemory( &bd, sizeof(bd) );
	bd.Usage = D3D11_USAGE_DEFAULT;
	bd.ByteWidth = sizeof( SVertex ) * m_nVertexCount;
	bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	bd.CPUAccessFlags = 0;
	bd.MiscFlags = 0;
	D3D11_SUBRESOURCE_DATA InitData; 
	ZeroMemory( &InitData, sizeof(InitData) );
	InitData.pSysMem = verts;

	if( FAILED( g_PG_pRenderer->m_pd3dDevice->CreateBuffer( &bd, &InitData, &m_pVertexBuffer ) ) )
		{
		PG_LOG_ERROR_SIMPLE("Failed to create constant buffer for pgPrimitiveCube!", -1);
		return false;
	}

	ZeroMemory(&bd, sizeof(bd));

	bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( WORD ) * m_nIndexCount;       
    bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
    bd.CPUAccessFlags = 0;
    bd.MiscFlags = 0;
    InitData.pSysMem = indices;

	if( FAILED( g_PG_pRenderer->m_pd3dDevice->CreateBuffer( &bd, &InitData, &m_pIndexBuffer ) ) )
		{
		PG_LOG_ERROR_SIMPLE("Failed to create constant buffer for pgPrimitiveCube!", -1);
        return false;
	}

	// Create the constant buffer
	bd.Usage = D3D11_USAGE_DEFAULT;
	bd.ByteWidth = sizeof(ConstantBuffer);
	bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	bd.CPUAccessFlags = 0;
    HRESULT hr = g_PG_pRenderer->m_pd3dDevice->CreateBuffer( &bd, NULL, &m_pConstantBuffer );
    if( FAILED( hr ) )
		{
		PG_LOG_ERROR_SIMPLE("Failed to create constant buffer for pgPrimitiveCube!", hr);
        return false;
	}

	

	return true;
}

void pgPrimitiveCube::PreRender()
{
	 ID3D11InputLayout *pInputLayout = g_PG_pRenderer->GetVertexShader(0).GetVertexInputLayout();
	 g_PG_pRenderer->m_pImmediateContext->IASetInputLayout(pInputLayout);

	  UINT stride = sizeof(SVertex);
	 UINT offset = 0;
	 g_PG_pRenderer->m_pImmediateContext->IASetVertexBuffers(0, 1, &m_pVertexBuffer, &stride , &offset);

	 g_PG_pRenderer->m_pImmediateContext->IASetIndexBuffer(m_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);

	 g_PG_pRenderer->m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
}

void pgPrimitiveCube::Render()
{
	ConstantBuffer cb;
	cb.mWorld = XMMatrixTranspose(GetWorldTransformMatrix());
    cb.mView = XMMatrixTranspose( g_PG_pRenderer->GetViewCamera()->GetViewMatrix() );
    cb.mProjection = XMMatrixTranspose( g_PG_pRenderer->GetViewCamera()->GetProjectionMatrix() );

	g_PG_pRenderer->m_pImmediateContext->UpdateSubresource( m_pConstantBuffer, 0, NULL, &cb, 0, 0 );

	g_PG_pRenderer->m_pImmediateContext->VSSetShader(g_PG_pRenderer->GetVertexShader(0).GetVertexShader(), NULL, 0);

	g_PG_pRenderer->m_pImmediateContext->VSSetConstantBuffers(0,1, &m_pConstantBuffer);

	g_PG_pRenderer->m_pImmediateContext->PSSetShader(g_PG_pRenderer->GetPixelShader(0).GetPixelShader(), NULL, 0);

	g_PG_pRenderer->m_pImmediateContext->DrawIndexed(m_nIndexCount, 0, 0);
}

void pgPrimitiveCube::PostRender()
{
}
